﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace DARE
{
    /// <summary>
    /// It represents an entity that can be draw and update.
    /// </summary>
    public abstract class AEntity : IUpdateable, IDrawable
    {
    
    #region fields

        protected string m_name;
        protected Vector2 m_position;
        protected Vector2 m_size;
        protected AEntity m_parent;
        protected Dictionary<string, AEntity> m_children;
        protected CRender2D m_render;
        protected bool m_updatable = true;
        protected bool m_drawable = true;

    #endregion
        
    #region properties

        public bool Updatable
        {
            get { return m_updatable; }
            set { m_updatable = value; }
        }

        public bool Drawable
        {
            get { return m_drawable; }
            set { m_drawable = value; }
        }

        public AEntity Parent
        {
            get { return m_parent; }
            set
            {
                if (m_parent != null)
                    m_parent.RemoveChild(this);
                else
                    m_render.UnregisterEntity(this);
                m_parent = value;
                if (m_parent != null)
                    m_parent.AddChild(this);
                else
                    m_render.RegisterEntity(this);
            }
        }

        public string Name { get { return m_name; } }

        public Vector2 Position
        {
            get { return m_position; }
            set
            {
                foreach (AEntity child in m_children.Values)
                    child.Position += value - m_position;
                m_position = value;
            }
        }

        public Vector2 Size
        {
            get { return m_size; }
            set
            {
                m_size = value;
            }
        }

    #endregion

    #region ctor

        public AEntity(string name, CRender2D render2D)
            : this(name, render2D, null)
        {

        }

        public AEntity(string name, CRender2D render2D, AEntity parent)
        {
            m_name = name;
            m_render = render2D;
            m_children = new Dictionary<string, AEntity>();
            if (parent == null)
                render2D.RegisterEntity(this);
            else
                parent.m_children.Add(name, this);
        }

    #endregion

    #region methods

        public AEntity AddChild(AEntity entity)
        {
            m_children.Add(entity.Name, entity);
            return this;
        }

        public AEntity RemoveChild(AEntity entity)
        {
            m_children.Remove(entity.Name);
            return this;
        }

        public AEntity RemoveAllChildren()
        {
            m_children.Clear();
            return this;
        }
        public abstract AEntity Clone(string name);
        public abstract AEntity Clone(string name, AEntity parent);

        public abstract void Update(GameTime gameTime);
        public abstract void Draw(GameTime gameTime);

    #endregion

    }
}
